using Microsoft.OpenApi.Models;
using Serilog.Events;
using Serilog;
using ztDataNet.Db;
using Microsoft.AspNetCore.HttpOverrides;
using System.Net;
using Quartz;

using ztDataNet;
using Microsoft.Extensions.Options;



// 创建Serilog
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .CreateBootstrapLogger();
try
{
    Log.Information("Starting web host");

    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.

    builder.Services.AddControllers();

    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My ztDataNet API 个人服务器数据终端接口", Version = "v1" });
        c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); // This line
        c.CustomSchemaIds(type => type.FullName); // 解决相同类名会报错的问题
                                                  //API接口文件路径

        var path = Path.Combine(AppContext.BaseDirectory, "ztDataNet.xml");
        c.IncludeXmlComments(path, true);
        c.OrderActionsBy(x => x.RelativePath);

    });
    builder.Services.AddStackExchangeRedisCache(options =>
    {
        options.Configuration = "119.45.240.39:6379,password=04985807,syncTimeout =5000"; // Replace with your Redis connection string
        options.InstanceName = "ztDataNet:";
    });
    builder.Services.AddSqlsugarSetup(builder.Configuration);
    //log日志注入
    builder.Services.AddSingleton<ILoggerHelper, LogHelper>();
    builder.Services.AddHttpClient();

    // 初始化 Serilog
    builder.Host.UseSerilog((ctx, lc) => lc
        .ReadFrom.Configuration(ctx.Configuration)
        .Enrich.FromLogContext());
    builder.Services.AddControllers(options =>
    {
        options.SuppressAsyncSuffixInActionNames = false;
        options.Filters.Add(typeof(GlobalExceptionsFilter));
    });
    // Configure Kestrel
    builder.WebHost.ConfigureKestrel(options =>
    {
        options.Listen(IPAddress.Any, 5000); // HTTP
        options.Listen(IPAddress.Any, 5001, listenOptions => // HTTPS
        {
            listenOptions.UseHttps("/var/lib/jenkins/workspace/zhangteng.cloud_nginx/zhangteng.cloud.pfx", "04985807");
        });
    });
    builder.Services.AddCors(policy =>
    {
        policy.AddPolicy("CorsPolicy", opt => opt
        .AllowAnyOrigin()
        .AllowAnyHeader()
        .AllowAnyMethod()
        .WithExposedHeaders("X-Pagination"));

        //policy.AddPolicy("CorsPolicy", builder =>
        //{
        //    builder.WithOrigins("http://localhost:8080")  // Replace with your specific origins
        //           .AllowAnyHeader()
        //           .AllowAnyMethod()
        //           .AllowCredentials(); // Allow credentials
        //});
    });

    builder.Services.AddMemoryCache();

    builder.Services.AddQuartz(q =>
    {
        q.UseMicrosoftDependencyInjectionJobFactory();

        q.AddJob<RssFetchJob>(opts =>
        {
            var jobKey = new JobKey("RssFetchJob");
            opts.WithIdentity(jobKey);
        });

        q.AddTrigger(opts => opts
            .ForJob(new JobKey("RssFetchJob"))
            .WithIdentity("RssFetchJob-trigger")
            .WithCronSchedule("0 0 8 1/1 * ? *")); // Every day at 8 AM

        // 添加 DataCheckJob
        q.AddJob<DataCheckJob>(opts =>
        {
            var jobKey = new JobKey("DataCheckJob");
            opts.WithIdentity(jobKey);
        });

        // 为 DataCheckJob 添加触发器，每分钟执行一次
        q.AddTrigger(opts => opts
            .ForJob(new JobKey("DataCheckJob"))
            .WithIdentity("DataCheckJob-trigger")
            .WithCronSchedule("0 * * * * ?")); // 每分钟
    });

    builder.Services.AddQuartzHostedService(
        q => q.WaitForJobsToComplete = true);

    var app = builder.Build();
    app.UseCors("CorsPolicy");
    // Configure the HTTP request pipeline.
    //if (app.Environment.IsDevelopment())
    //{
    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });
    app.UseForwardedHeaders(new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
    });

    //}
    app.UseMiddleware<RequestLoggingMiddleware>();
    app.UseSerilogRequestLogging(options =>
    {
        options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
        {
            var request = httpContext.Request;
            if (request.Query != null && request.Query.Any())
            {
                foreach (var item in request.Query)
                {
                    diagnosticContext.Set($"Query_{item.Key}", item.Value.ToString());
                }
            }
            if (request.HasFormContentType && request.Form != null)
            {
                foreach (var item in request.Form)
                {
                    diagnosticContext.Set($"Form_{item.Key}", item.Value.ToString());
                }
            }
        };
    });
    app.UseWebSockets();
    app.UseMiddleware<SshWebSocketMiddleware>();
    app.UseRouting();

    app.UseHttpsRedirection();

    app.UseAuthorization();

    app.MapControllers();

    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();
}

